﻿using System;
using System.Configuration;
using System.Data;
using System.Data.Linq;
using System.Data.SqlClient;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using CreateYourWorld.DataModels;
using CreateYourWorld.DataAccess.SqlServer;

namespace CreateYourWorld.DataAccess
{
    public class WorldRepository : IWorldRepository
    {
        private SqlDatabaseDataContext db = new SqlDatabaseDataContext(ConfigurationManager.
            ConnectionStrings["CreateYourWorld.DataAccess.SqlServer.Properties.Settings.CYW59ConnectionString"].ConnectionString);

        public SessionModel getSession(string username, string password)
        {
            try
            {
                // get playerId
                var accounts = from account in db.BASEDATA_ACCOUNTS
                               join player in db.BASEDATA_PLAYERS on account.ID equals player.ACCOUNT_ID
                               where account.EMAIL == username
                                  && account.PASSWORD == password
                               select player;
                Int64 playerID = accounts.First().ID;

                // set existing sessions for this playerId to false/delete them
                db.GAMEDATA_SESSIONS.DeleteAllOnSubmit(
                    from session in db.GAMEDATA_SESSIONS
                    where session.PLAYER_ID == playerID
                    select session);
                db.SubmitChanges();

                // add new session for this playerId and return new index
                GAMEDATA_SESSIONS newSession = new GAMEDATA_SESSIONS
                {
                    PLAYER_ID = playerID,
                    LAST_ACTION = DateTime.Now
                };
                db.GAMEDATA_SESSIONS.InsertOnSubmit(newSession);
                db.SubmitChanges();

                return new SessionModel { ID = newSession.ID, LastAction = newSession.LAST_ACTION };
            }
            catch { }
            return null;
        }

        public PlayerModel getPlayer(Int64 sessionID)
        {
            try
            {
                var playerData = from player in db.GAMEDATA_WORLD_PLAYERS
                                 join session in db.GAMEDATA_SESSIONS on player.PLAYER_ID equals session.PLAYER_ID
                                 where session.ID == sessionID
                                 select new PlayerModel
                                 {
                                     FieldID = player.FIELD_ID,

                                     LifePoints = player.LIFEPOINTS,
                                     Endurance = player.ENDURANCE,
                                     Strength = player.STRENGTH,
                                     Intelligence = player.INTELLIGENCE,
                                     Dexterity = player.DEXTERITY,
                                     PhysicalResistance = player.PHYSICAL_RESISTANCE,
                                     PoisonResistance = player.POISON_RESISTANCE,
                                     MagicalResistance = player.MAGICAL_RESISTANCE,
                                     FireResistance = player.FIRE_RESISTANCE,
                                     WaterResistance = player.WATER_RESISTANCE
                                 };
                return playerData.First();
            }
            catch (Exception ex)
            {
                return null;
            }
        }
        public PlayerBaseModel getPlayerData(Int64 sessionID)
        {
            try
            {
                var result = from player in db.BASEDATA_PLAYERS
                             join session in db.GAMEDATA_SESSIONS on player.ID equals session.PLAYER_ID
                             where session.ID == sessionID
                             select new PlayerBaseModel
                             {
                                 Name = player.NAME,
                                 Endurance = player.ENDURANCE,
                                 Strength = player.STRENGTH,
                                 Intelligence = player.INTELLIGENCE,
                                 Dexterity = player.DEXTERITY,
                                 PhysicalResistance = player.PHYSICAL_RESISTANCE,
                                 PoisonResistance = player.POISON_RESISTANCE,
                                 MagicalResistance = player.MAGICAL_RESISTANCE,
                                 FireResistance = player.FIRE_RESISTANCE,
                                 WaterResistance = player.WATER_RESISTANCE
                             };
                return result.First();
            }
            catch { }
            return null;
        }
        public bool updatePlayerPosition(Int64 sessionID, int movedX, int movedY)
        {
            try
            {
                var players = from player in db.GAMEDATA_WORLD_PLAYERS
                              join session in db.GAMEDATA_SESSIONS on player.PLAYER_ID equals session.PLAYER_ID
                              join field in db.GAMEDATA_WORLD_FIELDS on player.FIELD_ID equals field.ID
                              where session.ID == sessionID
                              select new PlayerModel
                              {
                                  ID = player.PLAYER_ID,
                                  WorldID = field.WORLD_ID,
                                  xPosition = field.X_POS,
                                  yPosition = field.Y_POS
                              };

                var fields = from field in db.GAMEDATA_WORLD_FIELDS
                             where field.WORLD_ID == players.First().WorldID
                                && field.X_POS == players.First().xPosition + movedX
                                && field.Y_POS == players.First().yPosition + movedY
                             select field.ID;

                var playerToUpdate = from player in db.GAMEDATA_WORLD_PLAYERS
                                     where player.PLAYER_ID == players.First().ID
                                     select player;

                playerToUpdate.First().FIELD_ID = fields.First();

                db.SubmitChanges();

                return true;
            }
            catch (Exception ex)
            {
            }
            return false;
        }

        public IQueryable<FieldModel> getWorldFields()
        {            
            try
            {
                var fields = from field in db.GAMEDATA_WORLD_FIELDS
                             select new FieldModel
                             {
                                 ID = field.ID,
                                 FieldType = field.FIELDTYPE_ID,
                                 WorldID = field.WORLD_ID,
                                 X = field.X_POS,
                                 Y = field.Y_POS
                             };
                return fields;                
            }
            catch (Exception ex)
            {
                return null;
            }
        }
        public FieldBaseModel getFieldData(int fieldType)
        {
            try
            {
                var fields = from field in db.BASEDATA_FIELDS
                             where field.ID == fieldType
                             select new FieldBaseModel
                             {
                                 ID = field.ID,
                                 Name = field.NAME,
                                 Description = field.DESCRIPTION,
                                 MapImageFilename = field.MAPIMGFILENAME,
                                 BigImageFilename = field.BACKIMGFILENAME,
                                 TimeToCross = field.TIMETOCROSS
                             };
                if (fields == null) return null;
                return fields.First();
            }
            catch (Exception ex)
            {
                return null;
            }
        }

        public IQueryable<CreatureModel> getFieldCreatures(Int64 fieldID)
        {
            try
            {
                var creatures = from creature in db.GAMEDATA_FIELD_CREATURES
                                where creature.FIELD_ID == fieldID
                                select new CreatureModel
                                {
                                    ID = creature.ID,
                                    CreatureType = creature.CREATURE_ID,
                                    FieldID = creature.FIELD_ID,
                                    
                                    LifePoints = creature.LIFEPOINTS,

                                    PhysicalDamage = creature.PHYSICAL_DAMAGE,
                                    MagicalDamage = creature.MAGICAL_DAMAGE,
                                    PoisonDamage = creature.POISON_DAMAGE,
                                    FireDamage = creature.FIRE_DAMAGE,
                                    WaterDamage = creature.WATER_DAMAGE,

                                    PhysicalResistance = creature.MAGICAL_RESISTANCE,
                                    MagicalResistance = creature.MAGICAL_RESISTANCE,
                                    PoisonResistance = creature.POISON_RESISTANCE,
                                    FireResistance = creature.FIRE_RESISTANCE,
                                    WaterResistance = creature.WATER_RESISTANCE,
                                };
                return creatures;                
            }
            catch (Exception ex)
            {
                return null;
            }
        }
        public CreatureBaseModel getCreatureData(int creatureType)
        {
            try
            {
                var creatures = from creature in db.BASEDATA_CREATURES
                                select new CreatureBaseModel
                                {
                                    ID = creature.ID,
                                    Name = creature.NAME,
                                    Description = creature.DESCRIPTION,

                                    Endurance = creature.ENDURANCE,

                                    PhysicalDamage = creature.PHYSICAL_DAMAGE,
                                    MagicalDamage = creature.MAGICAL_DAMAGE,
                                    PoisonDamage = creature.POISON_DAMAGE,
                                    FireDamage = creature.FIRE_DAMAGE,
                                    WaterDamage = creature.WATER_DAMAGE,

                                    PhysicalResistance = creature.PHYSICAL_RESISTANCE,
                                    MagicalResistance =creature.MAGICAL_RESISTANCE,
                                    PoisonResistance = creature.POISON_RESISTANCE,
                                    FireResistance = creature.FIRE_RESISTANCE,
                                    WaterResistance = creature.WATER_RESISTANCE,

                                    BigImageFilename = creature.IMGFILENAME
                                };
                if (creatures == null) return null;
                return creatures.First();
            }
            catch (Exception ex)
            {
                return null;
            }
        }

        public IQueryable<ItemModel> getFieldItems(Int64 fieldID)
        {
            try
            {
                var items = from item in db.GAMEDATA_FIELD_ITEMS
                            where item.FIELD_ID == fieldID
                            select new ItemModel
                            {
                                ID = item.ID,
                                ItemType = item.ITEM_ID,
                                Number = item.NUMBER
                            };
                return items;
            }
            catch (Exception ex) 
            {
                return null;
            }
        }
        public IQueryable<ItemModel> getCreatureItems(Int64 creatureID)
        {
            try
            {
                var items = from item in db.GAMEDATA_CREATURE_ITEMS
                            where item.CREATURE_ID == creatureID
                            select new ItemModel
                            {
                                ID = item.ID,
                                ItemType = item.ITEM_ID,                                
                                Number = item.NUMBER
                            };
                return items;
            }
            catch (Exception ex)
            {
                return null;
            }
        }
        public IQueryable<ItemModel> getPlayerItems(Int64 sessionID)
        {
            try
            {
                var items = from item in db.GAMEDATA_PLAYER_ITEMS
                            join session in db.GAMEDATA_SESSIONS on item.PLAYER_ID equals session.PLAYER_ID
                            where session.ID == sessionID
                            select new ItemModel
                            {
                                ID = item.ID,
                                ItemType = item.ITEM_ID,
                                Number = item.NUMBER
                            };
                return items;
            }
            catch (Exception ex)
            {
                return null;
            }
        }
        public ItemBaseModel getItemData(Int32 itemType)
        {
            try
            {
                var Items = from item in db.BASEDATA_ITEMS
                            where item.ID == itemType
                            select new ItemBaseModel
                            {
                                ID = item.ID,
                                Name = item.NAME,
                                Description = item.DESCRIPTION,
                                Imgfilename = item.IMGFILENAME
                            };
                return Items.First();
            }
            catch
            {
                return null;
            }
        }
    }
}
